package zero.common.config;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.JFinal;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.plugin.redis.Redis;
import com.jfinal.plugin.redis.RedisPlugin;
import com.jfinal.template.Engine;

import zero.common.model._MappingKit;
import zero.common.slf4j.Slf4jLogFactory;
import zero.common.swagger.routes.SwaggerRoutes;
import zero.common.utils.DruidKit;
import zero.security.model.Menu;
import zero.security.model.Org;
import zero.security.model.Role;
import zero.security.model.RoleMenu;
import zero.security.model.User;
import zero.security.shiro.ShiroPlugin;
import zero.security.shiro.directive.ShiroHasPermissionDirective;



/**
 * 本 demo 仅表达最为粗浅的 jfinal 用法，更为有价值的实用的企业级用法
 * 详见 JFinal 俱乐部: http://jfinal.com/club
 * 
 * API引导式配置
 */
public class MainConfig extends JFinalConfig {
	
	// 先加载开发环境配置，再追加生产环境的少量配置覆盖掉开发环境配置
	private static Prop config = PropKit.use("as_config_dev.txt")
						.appendIfExists("as_config_pro.txt");
	private WallFilter wallFilter;
	
	/**
	 * 运行此 main 方法可以启动项目，此main方法可以放置在任意的Class类定义中，不一定要放于此
	 * 
	 * 使用本方法启动过第一次以后，会在开发工具的 debug、run config 中自动生成
	 * 一条启动配置，可对该自动生成的配置再添加额外的配置项，例如 VM argument 可配置为：
	 * -XX:PermSize=64M -XX:MaxPermSize=256M
	 */
	public static void main(String[] args) {
		/**
		 * 特别注意：Eclipse 之下建议的启动方式
		 */
		JFinal.start("src/main/webapp", 8086, "/", 5);
		
		/**
		 * 特别注意：IDEA 之下建议的启动方式，仅比 eclipse 之下少了最后一个参数
		 */
		// JFinal.start("src/main/webapp", 80, "/");
	}
	
	/**
	 * 配置常量
	 */
	public void configConstant(Constants me) {

		me.setDevMode(config.getBoolean("devMode", false));
		me.setEncoding("utf-8");//设置和不设置的区别?
		me.setBaseUploadPath("upload/picture/");//设置和不设置的区别?
//		me.setJsonFactory(MixedJsonFactory.me());
		me.setLogFactory(new Slf4jLogFactory());//使用slf4j日志，可以整合其他类型的日志
		
	}
	
	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		me.setBaseViewPath("WEB-INF/html/");
		me.add(new AdminRoutes());//后台的路由
		me.add(new FrontRoutes());//前台的路由
		me.add(new WxRoutes());//微信端路由
		me.add(new MobileRoutes());//手机端路由
		me.add(new OpenRoutes());//第三方接口
		me.add(new SwaggerRoutes());//第三方接口
		
		me.add(new NormalUserRoutes());//普通用户路由
		
	}
	
	public void configEngine(Engine me) {
//		me.addSharedFunction("/common/_layout.html");
		me.addDirective("shiroHasPermission", ShiroHasPermissionDirective.class);
	}

	public static DruidPlugin getDruidPlugin() {
		return new DruidPlugin(config.get("jdbcUrl"), config.get("user"), config.get("password").trim());
	}
	
	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置 druid 数据库连接池插件
		DruidPlugin druidPlugin = new DruidPlugin(config.get("jdbcUrl"), config.get("user"), config.get("password").trim());
	    wallFilter = new WallFilter();              // 加强数据库安全
	    wallFilter.setDbType("mysql");
	    druidPlugin.addFilter(wallFilter);
	    druidPlugin.addFilter(new StatFilter());    // 添加 StatFilter 才会有统计数据		
		me.add(druidPlugin);
		
		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
		// 所有映射在 MappingKit 中自动化搞定
		_MappingKit.mapping(arp);
		me.add(arp);
		// 权限MAP
		arp.addMapping("sec_user", User.class);
		arp.addMapping("sec_org", Org.class);
		arp.addMapping("sec_role", Role.class);
//		arp.addMapping("sec_authority", Authority.class);
//		arp.addMapping("sec_resource", Resource.class);
		arp.addMapping("sec_menu", Menu.class);	
		arp.addMapping("sec_role_menu", RoleMenu.class);	
		
		// 配置shiro插件
		ShiroPlugin shiroPlugin = new ShiroPlugin();
		me.add(shiroPlugin);
		
		//sql模板
//        arp.setShowSql(config.getBoolean("devMode", false));
//        arp.getEngine().setSourceFactory(new ClassPathSourceFactory());
//        arp.addSqlTemplate("/sql/all_sqls.sql");
        
		//配置ehcache
		me.add(new EhCachePlugin());
		//配置调度器
//		Cron4jPlugin cp = new Cron4jPlugin("schedule.properties");		
//		me.add(cp);
		
		
	}
	
	public static DruidPlugin createDruidPlugin() {
		return new DruidPlugin(config.get("jdbcUrl"), config.get("user"), config.get("password").trim());
	}
	
	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		
	}
	
	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
		me.add(DruidKit.getDruidStatViewHandler()); // druid 统计页面功能
	}
	
    /**
     * 本方法会在 jfinal 启动过程完成之后被回调，详见 jfinal 手册
     */
	public void afterJFinalStart() {

		// 让 druid 允许在 sql 中使用 union
		// https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE-wallfilter
		wallFilter.getConfig().setSelectUnionCheck(false);
	}
	
}
